package com.humngyang.com.hmy.study.concurrency.myannoations.collection;


import com.google.common.collect.Lists;
import com.humngyang.com.hmy.study.concurrency.myannoations.ThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;


//
@ThreadSafe
public class CopyOnWriteArrayListExample {
    private static Logger log = LoggerFactory.getLogger(CopyOnWriteArrayListExample.class);

    //请求总数
    public static int clientTotal = 5000;
    //同时并发执行的线程数
    public static int threadTotal = 50;

    //利用guava创建一个Lists.newArrayList()集合，然后利用Collections将集合同步化，成为一个线程安全的集合
    public static List list = new CopyOnWriteArrayList();

    public static void main(String[] args) throws InterruptedException {
        //创建线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //信号量是能够控制线程的并发量，所以可以通过线程数来控制并发的数量
        final Semaphore semaphore = new Semaphore(threadTotal);
        //CountDownLatch能够阻塞线程，并且满足特定的情况继续执行。也就是说在执行完总的请求之后在执行
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int index = 0; index < clientTotal; index++) {
//            final int count = index;
            executorService.execute(() -> {
                try {
                    //利用信号量控制是否允许执行
                    semaphore.acquire();
                    copyOnWriteArrayListdd();
                    //每次执行之后需要释放当前的线程
                    semaphore.release();
                } catch (Exception e) {
                    log.error("Exception", e);
                }
                //每执行一次，请求的次数就减一
                countDownLatch.countDown();
            });
        }
        //能够保证countDownLatch当前的请求数已经减为0
        countDownLatch.await();
        //当所有的执行完毕之后，如果不需要线程池的话，可以关闭线程池
        executorService.shutdown();
        log.info("count{}", list.size());
    }

    public static void copyOnWriteArrayListdd() {
        list.add(1);
    }
}
